//
//  KSImageUtil.m
//  test
//
//  Created by Mac on 2018/12/29.
//

#import "KSImageUtil.h"

@implementation KSImageUtil

///MARK:-修正图片方向
UIImage* ks_imageDirection(UIImage* src){
    if (src.imageOrientation == UIImageOrientationUp)
        return src;
    
    CGAffineTransform transform = CGAffineTransformIdentity;
    
    switch (src.imageOrientation) {
        case UIImageOrientationDown:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, src.size.width, src.size.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;
            
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
            transform = CGAffineTransformTranslate(transform, src.size.width, 0);
            transform = CGAffineTransformRotate(transform, M_PI_2);
            break;
            
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, src.size.height);
            transform = CGAffineTransformRotate(transform, -M_PI_2);
            break;
        default:
            break;
    }
    
    switch (src.imageOrientation) {
        case UIImageOrientationUpMirrored:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, src.size.width, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
            
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, src.size.height, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
        default:
            break;
    }
    
    CGContextRef ctx = CGBitmapContextCreate(NULL, src.size.width, src.size.height,
                                             CGImageGetBitsPerComponent(src.CGImage), 0,
                                             CGImageGetColorSpace(src.CGImage),
                                             CGImageGetBitmapInfo(src.CGImage));
    CGContextConcatCTM(ctx, transform);
    switch (src.imageOrientation) {
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            // Grr...
            CGContextDrawImage(ctx, CGRectMake(0,0,src.size.height,src.size.width), src.CGImage);
            break;
            
        default:
            CGContextDrawImage(ctx, CGRectMake(0,0,src.size.width,src.size.height), src.CGImage);
            break;
    }
    
    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
    UIImage *img = [UIImage imageWithCGImage:cgimg];
    CGContextRelease(ctx);
    CGImageRelease(cgimg);
    return img;
}

///MARK:-同步按质量压缩图片
NSData* ks_imageCompressQuality(UIImage* src, NSUInteger byte){
    src = _ksprepareImageSize(src);
    
    NSData* imgData = UIImageJPEGRepresentation(src, 1);
    
    if (imgData.length < byte) {
        return imgData;
    }
    
    CGFloat max = 1;
    CGFloat min = 0.000001;
    CGFloat quality = (max + min) / 2;
    CGFloat lastLength = 0;
    
    while (byte - imgData.length > 1000 && lastLength != imgData.length) {
        
        lastLength = imgData.length;
        
        imgData = UIImageJPEGRepresentation(src, quality);
        
        if (imgData.length > byte) {
            max = quality;
        }else if (imgData.length < byte){
            min = quality;
        }
        quality = (max + min) / 2;
    }
    
    return imgData;
}


///MARK:-异步按质量压缩图片
void ks_imageAsynCompressQuality(NSArray<UIImage*>* srcs,
                                 NSUInteger byte,
                                 CompressImageComplete complete){
    // 2020.07.14注释
//    dispatch_async(_kscompress_queue(), ^{
        
        NSMutableArray<NSData*>* imgs = [NSMutableArray arrayWithCapacity:srcs.count];
        
        for (UIImage* src in srcs) {
            [imgs addObject:ks_imageCompressQuality(src, byte)];
        }
        
        if (complete) {
            complete(imgs);
        }
        
//    });
}

///MARK:-同步按尺寸压缩图片
NSData* ks_imageCompressSize(UIImage* src ,NSUInteger byte){
    
    src = _ksprepareImageSize(src);

    NSData* imgData = UIImageJPEGRepresentation(src, 1.0);
    
    if (byte > imgData.length) {
        return imgData;
    }
    
    CGSize imgSize = src.size;
    CGFloat max = 1.0;
    CGFloat min = 0.1;
    CGFloat scale = (max + min) / 2;
    
    while (byte - imgData.length > 1000 && ABS(scale - min) >= 0.000001) {
        CGSize size = CGSizeMake(imgSize.width * scale, imgSize.height * scale);
        UIImage* img = ks_imageResize(src, size);
        imgData = UIImageJPEGRepresentation(img, 1.0);
        
        if (imgData.length > byte) {
            max = scale;
        }else if (imgData.length < byte){
            min = scale;
        }
        scale = (max + min) / 2;
    }
    
    return imgData;
}

///MARK:-异步按尺寸压缩图片
void ks_imageAsynCompressSize(NSArray<UIImage*>* srcs,
                              NSUInteger byte,
                              CompressImageComplete complete){
    
    dispatch_async(_kscompress_queue(), ^{
        
        NSMutableArray<NSData*>* imgs = [NSMutableArray arrayWithCapacity:srcs.count];
        
        for (UIImage* src in srcs) {
            [imgs addObject:ks_imageCompressSize(src, byte)];
        }
        
        if (complete) {
            complete(imgs);
        }
        
    });
}

///MARK:-异步按质量和尺寸压缩图片
void ks_imageAsynCompress(NSArray<UIImage*>* srcs,
                          NSUInteger byte,
                          CompressImageComplete complete){
//    dispatch_async(_kscompress_queue(), ^{
    
        NSMutableArray<NSData*>* imgs = [NSMutableArray arrayWithCapacity:srcs.count];
        
        for (UIImage* src in srcs) {
            
            NSData* data = ks_imageCompressQuality(src, byte);
            UIImage* img = [UIImage imageWithData:data];

            if (data.length > byte) {
                data = ks_imageCompressSize(img, byte);
            }
            
            [imgs addObject:data];
        }
        
        if (complete) {
            complete(imgs);
        }
        
//    });
}

///MARK:-同步修改图片尺寸
UIImage* ks_imageResize(UIImage* src, CGSize size){
    
    UIGraphicsBeginImageContextWithOptions(size, NO, 0);

    [src drawInRect:CGRectMake(0, 0, size.width, size.height)];
    
    UIImage* img = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
        
    return img;
}

///MARK:-压缩前预先设置最大1024的尺寸
UIImage* _ksprepareImageSize(UIImage* src){
    
    CGSize srcSize = CGSizeMake(src.size.width * src.scale, src.size.height * src.scale);
    CGSize size = CGSizeZero;
    CGFloat max = 1024;
    BOOL shouldResize = NO;
    
    if (srcSize.width > srcSize.height) {
        if (srcSize.width > max) {
            size.width = max;
            size.height = max / srcSize.width * srcSize.height;
            shouldResize = YES;
        }
    }else if (srcSize.width < srcSize.height){
        if (srcSize.height > max) {
            size.height = max;
            size.width = max / srcSize.height * srcSize.width;
            shouldResize = YES;
        }
    }else{
        if (srcSize.width > max) {
            size.width = max;
            size.height = max;
            shouldResize = YES;
        }
    }
    if (shouldResize) {
        return ks_imageResize(src, size);
    }else{
        return src;
    }
}

///MARK:-获取异步线程
dispatch_queue_t _kscompress_queue(){
    static dispatch_queue_t queue = NULL;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        queue = dispatch_queue_create("com.kscompress.queue", NULL);
    });
    return queue;
}

@end
